package com.manong.controller;

import com.manong.config.redis.RedisService;
import com.manong.entity.Permission;
import com.manong.entity.User;
import com.manong.entity.UserInfo;
import com.manong.utils.JwtUtils;
import com.manong.utils.MenuTree;
import com.manong.utils.Result;
import com.manong.vo.RouterVo;
import com.manong.vo.TokenVo;
import io.jsonwebtoken.Jwts;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/sysUser")
public class SysUserController {
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private RedisService redisService;

    /**
     * 刷新token
     * @param request
     * @return
     */
    @PostMapping("/refreshToken")
    public Result refreshToken(HttpServletRequest request){

        String token = request.getHeader("token");
        if(ObjectUtils.isEmpty(token)){
            token = request.getParameter("token");
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails = (UserDetails)authentication.getPrincipal();
        String newToken = "";
        if(jwtUtils.validateToken(token,userDetails)){
            newToken= jwtUtils.refreshToken(token);
        }
        long jwt = Jwts.parser()
                .setSigningKey(jwtUtils.getSecret())
                .parseClaimsJws(newToken.replace("jwt_", ""))
                .getBody().getExpiration().getTime();

        String oldToken = "token_"+token;
        redisService.del(oldToken);
        String newTokenKey = "token_"+newToken;
        redisService.set(newTokenKey,newToken,jwtUtils.getExpiration()/1000);

        return Result.ok(new TokenVo(jwt,newToken)).message("token刷新成功");
    }

    /**
     * 获取登录用户信息
     * @return
     */
    @GetMapping("/getInfo")
    public Result getInfo(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if(authentication==null){
            return Result.error().message("获取用户信息失败");
        }
        User user = (User)authentication.getPrincipal();

        List<Permission> permissionList = user.getPermissionList();
        Object[] roles = permissionList.stream()
                .filter(Objects::nonNull)
                .map(Permission::getCode)
                .toArray();
        UserInfo userInfo = new UserInfo(user.getId(),user.getNickName(),user.getAvatar(),null,roles);
        return Result.ok(userInfo).message("获取用户信息成功");
    }

    /**
     * 获取菜单列表
     * @return
     */
    @GetMapping("/getMenuList")
    public Result getMenuList(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        User user = (User)authentication.getPrincipal();

        List<Permission> permissionList = user.getPermissionList();
        List<Permission> collect = permissionList.stream().filter(item -> item != null && item.getType() != 2)
                .collect(Collectors.toList());
        List<RouterVo> routerVos = MenuTree.makeRouter(collect, 0L);
        return Result.ok(routerVos).message("获取菜单列表成功");
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request, HttpServletResponse response){
        String token = request.getHeader("token");

        if(ObjectUtils.isEmpty(token)){
            token = request.getParameter("token");
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication!=null){
            new SecurityContextLogoutHandler().logout(request,response,authentication);
            redisService.del("token_"+token);
            return Result.ok().message("退出成功");
        }
        return Result.error().message("退出失败");
    }
}
